﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;


namespace BubbleSurvival
{
    /// <summary>
    /// 2D-s kamera manager-e
    /// <para>input kezelése</para>
    /// <para>lock kezelése</para>
    /// </summary>
    public class CameraManager
    {

        Camera camera;                          // camera
        MouseState OldMouseState;               // egér kezelépséhez

        const int SPEED = 10;                   // camera mozgatásának sebessége
        float ScrollWheelChange;                // camera zoom-hoz
        float smoothZoomValue;                  // finom közelítés / távolítás

        const int SCREENOFFSET = 30;            // "ablak keret"
        const float SMOOTHZOOMSTEP = 0.03f;
        const float SMOOTHZOOMCORR = 0.005f;
        const float CAMCORR = 0.001f;
        const float DEFZOOM = 0.5f;
        const float MAXZOOM = 1.0f;
        const float MINZOOM = 0.3f;

        public float Zoom
        {
            get { return camera.Zoom; }
            set { camera.Zoom = value; }
        }

        /// <summary>
        /// A camera pos-t eltolja egy Vector2-vel
        /// </summary>
        public void Move(Vector2 amount)
        {
            camera.Move(amount);
        }

        public Vector2 Pos
        {
            get { return camera.Pos; }
            set { camera.Pos = value; }
        }

        // Konstruktor
        public CameraManager()
        {
            camera = new Camera();
            reset_cam();
        }


        // Update
        public void Update(GameTime gameTime)
        {

            // W,A,S,D kamera mozgatás
            if (Keyboard.GetState().IsKeyDown(Keys.A) || Keyboard.GetState().IsKeyDown(Keys.Left))
            {
                camera.Move(new Vector2(-SPEED, 0));
            }

            if (Keyboard.GetState().IsKeyDown(Keys.D) || Keyboard.GetState().IsKeyDown(Keys.Right))
            {
                camera.Move(new Vector2(SPEED, 0));
            }

            if (Keyboard.GetState().IsKeyDown(Keys.W) || Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                camera.Move(new Vector2(0, -SPEED));
            }

            if (Keyboard.GetState().IsKeyDown(Keys.S) || Keyboard.GetState().IsKeyDown(Keys.Down))
            {
                camera.Move(new Vector2(0, SPEED));
            }

            // SPACE - camera reset
            if (Keyboard.GetState().IsKeyDown(Keys.Space))
            {
                reset_cam();
            }

            // camera zoom kezelése (egérgörgő)
            MouseState CurrentMouseState = Mouse.GetState();
            if (CurrentMouseState.ScrollWheelValue != OldMouseState.ScrollWheelValue)
            {
                ScrollWheelChange = (float)(OldMouseState.ScrollWheelValue - CurrentMouseState.ScrollWheelValue);
                if (ScrollWheelChange < 0)
                {
                    smoothZoomValue += SMOOTHZOOMSTEP;

                    if (camera.Zoom > MAXZOOM || smoothZoomValue > MAXZOOM)
                    {
                        camera.Zoom = MAXZOOM;
                        smoothZoomValue = MAXZOOM;
                    }

                }
                else
                {

                    if (smoothZoomValue > MINZOOM)
                    {
                        smoothZoomValue -= SMOOTHZOOMSTEP;
                    }

                }
            }

            //// MidMouseButton: zoom alaphelyzetbe
            //if (CurrentMouseState.MiddleButton == ButtonState.Pressed && OldMouseState.MiddleButton == ButtonState.Released)
            //{
            //    //camera.Pos = ((Game1)Game).get_mouse_vpos();
            //    camera.Zoom = DEFZOOM;
            //    smoothZoomValue = DEFZOOM;
            //}

            // Ha az egér a képernyő szélén van: camera eltolása
            if (CurrentMouseState.X >= VideoOptionsMenuScreen.Resolution.X - SCREENOFFSET)
            {
                camera.Move(new Vector2(SPEED, 0));
            }
            if (CurrentMouseState.Y >= VideoOptionsMenuScreen.Resolution.Y - SCREENOFFSET)
            {
                camera.Move(new Vector2(0, SPEED));
            }
            if (CurrentMouseState.X <= SCREENOFFSET)
            {
                camera.Move(new Vector2(-SPEED, 0));
            }
            if (CurrentMouseState.Y <= SCREENOFFSET)
            {
                camera.Move(new Vector2(0, -SPEED));
            }

            // smooth zoom korrigálás
            if (!almost(camera.Zoom, smoothZoomValue))
            {
                if (smoothZoomValue < camera.Zoom)
                {
                    camera.Zoom -= SMOOTHZOOMCORR;
                }
                else
                {
                    camera.Zoom += SMOOTHZOOMCORR;
                }
            }
            else
            {
                camera.Zoom = smoothZoomValue;
            }

            // camera lock esetén a viselkedés
            //foreach (var bubble in bubbleList)
            //{
            //    if (bubble.LockedCamera)
            //    {
            //        camera.Pos = bubble.Position;
            //    }
            //}

            // Az "előző" mouseState rögzítése
            OldMouseState = CurrentMouseState;


        }

        // camera resetelése: zoom és pos alaphelyzetbe
        public void reset_cam()
        {
            camera.Zoom = DEFZOOM;
            smoothZoomValue = DEFZOOM;
            camera.Pos = new Vector2( 0, 0);
        }

        // camera korrigációhoz
        public static bool almost(float a, float b)
        {
            if (Math.Abs(a - b) < CAMCORR)
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// A Draw-hoz szükséges mtx-transzf.
        /// </summary>
        public Matrix CreateTransformatedMatrix(GraphicsDevice graphicsDevice)
        {
            return camera.CreateTransformatedMatrix(graphicsDevice);
        }

    }
}